package com.onpositive.datamap.compare;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashSet;

import com.onpositive.datamap.IDataPropertyValue;
import com.onpositive.datamap.core.IDataObject;
import com.onpositive.datamap.core.RepositoryUtil;
import com.onpositive.datamap.values.impl.LinkParser;
import com.onpositive.datamap.values.impl.PlainTextTokenAcceptor;
import com.onpositive.datamap.values.impl.ValueSequence;
import com.onpositive.semantic.model.api.property.IProperty;

public class SpecPartsBuilder {

	public static final class Counter extends PlainTextTokenAcceptor {
		int k = 0;

		@Override
		public void acceptExternalIdentifier(String text, String url,
				String propertyid) {
			String thumbnailUrl = RepositoryUtil.getThumbnailUrl(url, 48);
			if (thumbnailUrl != null) {
				k++;
			}
			super.acceptExternalIdentifier(text, url, propertyid);
		}
	}

	public static ArrayList<SpecificationPart> createSpecParts(
			IDataObject object) {
		IDataPropertyValue[] actual = object.getProperties();
		Arrays.sort(actual, new Comparator<IDataPropertyValue>() {

			@Override
			public int compare(IDataPropertyValue o1, IDataPropertyValue o2) {
				return group(o1).compareTo(group(o2));
			}
		});
		SpecificationPart current = null;
		ArrayList<SpecificationPart> specParts = new ArrayList<SpecificationPart>();
		ArrayList<SpecificationPart> specMParts = new ArrayList<SpecificationPart>();
		SpecificationPart general = new SpecificationPart();
		general.title = "General";

		for (IDataPropertyValue m : actual) {
			Object value = m;

			String id = m.getProperty().id().replace('_', ' ');
			if (id.equals("crew") || id.equals("designer")//FIXME
					|| id.equals("number built") || id.equals("status")
					|| id.equals("primary user")
					|| id.equals("national origin")
					|| id.equals("manufacturer") || id.equals("number built")
					|| id.equals("type") || id.equals("general")) {
				general.properties.add(m);
				continue;
			}
			if (value instanceof ValueSequence) {
				SpecificationPart t = new SpecificationPart();
				t.title = m.getProperty().name();
				ValueSequence s = (ValueSequence) value;
				Object[] parts = s.getParts();
				int mm = 0;
				if (parts.length > 1) {
					for (Object o : parts) {
						String string = o.toString();
						ValueSequence propertyValue = new ValueSequence(
								m.getProperty(), null, new String[] { string });
						t.properties.add(propertyValue);
						Counter acceptor = new Counter();
						LinkParser.parseHyperlink(string, acceptor, m
								.getProperty().getId());
						if (acceptor.k == 1) {
							mm++;
						}
					}
					if (mm >= parts.length / 2) {
						t.kind = SpecificationPart.KIND_MULTI_OBJECT;
					} else {
						t.kind = SpecificationPart.KIND_SIMPLE_MULTI_OBJECT;
					}
					specMParts.add(t);
					continue;
				}
			}
			if (current == null || !current.title.equals(group(m))) {
				if (current != null) {
					specParts.add(current);
				}
				SpecificationPart t = new SpecificationPart();
				t.title = group(m);
				// tableModel.addItem(t);

				current = t;
			}
			current.properties.add(m);
		}
		if (current != null) {
			specParts.add(current);
		}
		specParts.addAll(specMParts);
		if (general.properties.size() > 0) {
			specParts.add(0, general);
		}
		for (SpecificationPart p : specParts) {
			if (p.title.equals("M")) {
				p.title = "Dimensions";
			}
			if (p.title.equals("kg")) {
				p.title = "Weight & Loading";
			} else if (p.title.equals("km/h")) {
				p.title = "Speed";
			} else if (p.title.equals("date")) {
				p.title = "Notable dates";
			} else if (p.title.equals("W")) {
				p.title = "Engine & Power";
			} else if (p.title.equals("value sequence")) {
				p.title = "Other";
			} else {
				p.title = Character.toUpperCase(p.title.charAt(0))
						+ p.title.substring(1);
			}
			Collections.sort(p.properties,
					new Comparator<IDataPropertyValue>() {

						public int compare(IDataPropertyValue lhs,
								IDataPropertyValue rhs) {
							String group = group(lhs);
							String group1 = group(rhs);
							int r = group.compareTo(group1);
							if (r != 0) {
								return -r;
							}
							return lhs.getProperty().id()
									.compareTo(rhs.getProperty().id());
						}
					});
		}

		return specParts;
	}

	protected static String group(IDataPropertyValue m) {
		String group = m.getProperty().group();
		if (m.getProperty().id().equals("thrust_weight")) {
			return "W";
		}
		if (m.getProperty().id().equals("ceiling")) {
			return "Range & Ceiling";
		}
		if (m.getProperty().id().startsWith("number")) {
			return "Engine & Power";
		}
		if (m.getProperty().id().contains("range")) {
			return "Range & Ceiling";
		}
		if (group.startsWith("kg")) {
			return "kg";
		}
		if (group.equals("N")) {
			return "W";
		}
		if (group.startsWith("m")) {
			return "M";
		}
		return group;
	}

	public static LinkedHashSet<IProperty> createSpecParts(
			IDataObject[] displayedObject) {
		LinkedHashSet<IProperty>rs=new LinkedHashSet<IProperty>();
		for (IDataObject o:displayedObject){
			IDataPropertyValue[] properties = o.getProperties();
			for (IDataPropertyValue v:properties){
				rs.add(v.getProperty());
			}
		}
		return rs;
	}
}
